package cn.master.volley.models.response.listener;

import android.os.Message;
import android.util.Log;

import com.fasterxml.jackson.databind.JsonMappingException;
import com.ta.internal.multipart.upload.HttpType;
import com.ta.internal.multipart.upload.TaMultiPartUploader;
import com.ta.internal.multipart.upload.UploadParams;

import java.util.List;

import cn.master.volley.BuildConfig;
import cn.master.volley.models.pojo.Wrapper;
import cn.master.volley.models.response.handler.ResponseHandler;

/**
 * 监听返回信息，统一处理错误信息
 * 
 * @param <T>
 *            一个与 {@link Wrapper#getData()} 数据结构匹配的数据实体类，由调用者指定
 */
public class ResponseForMultiPartListener<T> extends TaMultiPartUploader {

	private static final String TAG = ResponseForMultiPartListener.class
			.getSimpleName();

	private ResponseHandler mHandler = null;
	private ResolveJson<T> mResolveJson = null;

	/**
	 * 构造方法
	 * 
	 * @param handler
	 * @param resolveJson
	 *            数据解析接口 , 如果该对象为 null , 则
	 *            {@link ResponseForMultiPartListener#mResolveJson} 的默认实现为
	 *            {@link ResolveJsonHelper#resolveJson2String} ,
	 *            {@link ResponseForMultiPartListener} 类的泛型类型为 {@link String} ,
	 *            并且
	 *            {@link ResponseForMultiPartListener#succeed(Message)}
	 *            可转变为
	 *
	 * @param url
	 * @param filesparams
	 * @param params
	 */
	public ResponseForMultiPartListener(ResponseHandler handler,
			ResolveJson<T> resolveJson,  HttpType httpType,String url,
			List<UploadParams> filesparams, List<UploadParams> params) {
		super(httpType,url, filesparams, params);
		this.mHandler = handler;
		if (resolveJson != null) {
			this.mResolveJson = resolveJson;
		}
	}

	/**
	 * 构造方法
	 * 
	 * @param handler
	 *            </br>数据解析时，{@link ResponseForMultiPartListener#mResolveJson}
	 *            的默认实现为 {@link ResolveJsonHelper#resolveJson2String} ,
	 *            {@link ResponseForMultiPartListener} 类的泛型类型为 {@link String} ,
	 *            并且
	 *            {@link ResponseForMultiPartListener#succeed(Message)}
	 *            可转变为
	 *
	 */
	public ResponseForMultiPartListener(ResponseHandler handler,HttpType httpType, String url,
			List<UploadParams> filesparams, List<UploadParams> params) {
		this(handler, null,httpType, url, filesparams, params);
	}

	@Override
	public void onSuccessUpload(final String response) {
		if (BuildConfig.DEBUG)
			Log.e(TAG, response);

		if (mHandler == null) {
			return;
		}
		// 开启线程用来处理数据
		new Thread(new Runnable() {
			@Override
			public void run() {
				dataProcessing(response);
			}
		}).start();
	}

	/**
	 * 数据处理（Json解析及数据分发）
	 * 
	 * @param response
	 */
	@SuppressWarnings("unchecked")
	private void dataProcessing(String response) {
		try {
			Wrapper<T> wrapper = null;
			if (mResolveJson == null) {
				mResolveJson = (ResolveJson<T>) ResolveJsonHelper.resolveAndIgnoreData;
			}
			try {
				wrapper = mResolveJson.resolve(response);
			} catch (JsonMappingException e) {
				mResolveJson = (ResolveJson<T>) ResolveJsonHelper.resolveJson2String;
				wrapper = mResolveJson.resolve(response);
			}
			Message msg = new Message();
			if (wrapper.getCode() != Wrapper.SUCCESS) {
				// Token无效，说明没有登陆或Token已经过期
				if (wrapper.getCode() == Wrapper.TOKEN_INVALID
						|| wrapper.getCode() == Wrapper.VERIFICATION_FAILED) {
					msg.what = ResponseHandler.INVALID_USER;
				} else {
					msg.what = ResponseHandler.FAIL;
				}
				msg.obj = wrapper.getData();
				mHandler.sendMessage(msg);
				return;
			}
			msg.what = ResponseHandler.SUCCEED;
			msg.obj = wrapper.getData();
			succeed(msg);
		} catch (Exception e) {
			Log.e( TAG , "Data1 processing failed ==> "+Log.getStackTraceString(new Throwable())+"\n"+e.getMessage() );
			mHandler.sendEmptyMessage(ResponseHandler.ERROR);
		}
	}

	@Override
	public void onUploadFaild(String error) {
		if (mHandler == null) {
			return;
		}
		Log.e( TAG , error );
		mHandler.sendEmptyMessage(ResponseHandler.CONNECTION_EXCPTION);
	}

	@Override
	public void onUploadProgress(int progress) {
		Message msg = new Message();
		msg.what = ResponseHandler.UPLOADING;
		msg.arg1 = progress;
		mHandler.sendMessage(msg);
	}

	/**
	 * 该方法由异步线程调用执行，负责给主线程的 Handler 发送成功消息。</br> 子类可重写此方法，可更改 message
	 * 中的数据（数据重组）或进行其它的数据处理
	 * 
	 * @param message
	 *            该 message 已包含了需要返回的成功码及 data 数据
	 * @return
	 */
	public void succeed(Message message) {
		mHandler.sendMessage(message);
	}

}
